home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / cdsend / convert.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  3KB  |  120 lines

  1. #include <stdio.h>
  2. #include "cdsend.h"
  3.  
  4. #define A    1
  5. #define B    7
  6.  
  7. static int d;
  8. static int prev_i, cur_i;
  9. static int rate_i = IN_RATE, rate_o = OUT_RATE;
  10. static short outbuf[(CDDA_NUMSAMPLES/2)*OUT_RATE/IN_RATE + 1];
  11.  
  12. #define ZEROTRAP    /* turn on the trap as per the MIL-STD */
  13. #define BIAS 0x84   /* define the add-in bias for 16 bit samples */
  14. #define CLIP 32635
  15.  
  16. static unsigned char
  17. st_linear_to_ulaw(int sample)
  18. {
  19.     static int exp_lut[256] = {0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
  20.                    4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
  21.                    5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
  22.                    5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
  23.                    6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
  24.                    6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
  25.                    6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
  26.                    6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
  27.                    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
  28.                    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
  29.                    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
  30.                    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
  31.                    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
  32.                    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
  33.                    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
  34.                    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7};
  35.     int sign, exponent, mantissa;
  36.     unsigned char ulawbyte;
  37.  
  38.     /* Get the sample into sign-magnitude. */
  39.     sign = (sample >> 8) & 0x80; /* set aside the sign */
  40.     if (sign != 0)
  41.         sample = -sample; /* get magnitude */
  42.     if (sample > CLIP)
  43.         sample = CLIP; /* clip the magnitude */
  44.  
  45.     /* Convert from 16 bit linear to ulaw. */
  46.     sample = sample + BIAS;
  47.     exponent = exp_lut[( sample >> 7 ) & 0xFF];
  48.     mantissa = ( sample >> ( exponent + 3 ) ) & 0x0F;
  49.     ulawbyte = ~ ( sign | ( exponent << 4 ) | mantissa );
  50. #ifdef ZEROTRAP
  51.     if (ulawbyte == 0)
  52.         ulawbyte = 0x02; /* optional CCITT trap */
  53. #endif
  54.  
  55.     return ulawbyte;
  56. }
  57.  
  58. void
  59. init_convert(void)
  60. {
  61.     d = -OUT_RATE;
  62.     prev_i = cur_i = 0;
  63. }
  64.  
  65. void
  66. convert_audio_and_print(short *audio, int nsamples, int linear)
  67. {
  68.     int cur_o;
  69.     short *outp = outbuf;
  70. #if !defined(A) || !defined(B)
  71.     int ab = a + b;
  72. #endif
  73.     int ld = d, lp = prev_i, lc = cur_i;    /* local copy (register?) */
  74.  
  75. #if !defined(A) || !defined(B)
  76.     /* some efficiency hacks */
  77.     ab *= 2;
  78.     b *= 2;
  79. #endif
  80.  
  81.     for (;;) {
  82.         while (ld < 0) {
  83.             if (nsamples == 0) {
  84.                 d = ld;
  85.                 prev_i = lp;
  86.                 cur_i = lc;
  87.  
  88.                 if (linear) {
  89.                     write(1, (char *) outbuf,
  90.                           sizeof(short) * (outp - outbuf));
  91.                 }
  92.                 return;
  93.             }
  94.             lp = lc;
  95. #if defined(A) && defined(B)
  96.             lc = (A * (audio[0] + audio[1]) + 2*B * lp) / (2*(A+B));
  97. #else
  98.             /* depends on efficiency hacks */
  99.             lc = (a * (audio[0] + audio[1]) + b * lp) / ab;
  100. #endif
  101.             nsamples--;
  102.             audio += 2;
  103.             ld += OUT_RATE;
  104.         }
  105. #if IN_RATE < OUT_RATE
  106.         while (ld >= 0)
  107. #endif
  108.         {
  109.             cur_o = (lp * ld + lc * (OUT_RATE - ld)) / OUT_RATE;
  110.             if (linear) {
  111.                 *outp++ = cur_o;
  112.             } else {
  113.                 /* not efficient at all */
  114.                 putchar(st_linear_to_ulaw(cur_o));
  115.             }
  116.             ld -= IN_RATE;
  117.         }
  118.     }
  119. }
  120.